package com.firefly.admin.common.service.impl;

import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.firefly.admin.common.enums.ResultCodeEnum;
import com.firefly.admin.common.utils.DateUtil;
import com.firefly.admin.common.vo.Result;
import io.minio.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import com.firefly.admin.common.service.FtpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;

@Service
@Slf4j
public class FtpServiceImpl implements FtpService {
    private static final String DATE_FORMAT = "yyyy/MM/dd";

    @Value("${minio.bucketName}")
    private String bucketName;

    @Value("${minio.agentMinioUrl}")
    private String agentMinioUrl;

    private static final String BUCKET_PARAM = "${bucket}";

    private static final String READ_WRITE = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucket\",\"s3:ListBucketMultipartUploads\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:DeleteObject\",\"s3:GetObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\",\"s3:AbortMultipartUpload\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "/*\"]}]}";


    @Autowired
    private MinioClient minioClient;

    /**
     * 公共文件上传接口
     *
     * @param file 文件信息
     * @return 上传结果
     */
    @Override
    public com.firefly.admin.common.vo.Result<String> uploadFile(MultipartFile file) {
        String url = "";
        if (file == null) {
            return com.firefly.admin.common.vo.Result.getResult(ResultCodeEnum.FILE_UPLOAD_EXCEPTION);
        }
        try {
            String path = DateUtil.getNowDateString(DATE_FORMAT);
            url = upload(file, path, "admin");
        } catch (Exception e) {
            e.printStackTrace();
            return com.firefly.admin.common.vo.Result.getResult(ResultCodeEnum.FILE_UPLOAD_EXCEPTION);
        }
        return Result.success(url);
    }

    /**
     * 文件上传接口
     *
     * @param file         文件信息
     * @param bizPath      上传地址
     * @param customBucket 自定义桶名称
     * @return 文件地址
     */
    @Override
    public String upload(MultipartFile file, String bizPath, String customBucket) {
        if (StringUtils.isNotEmpty(customBucket)) {
            bucketName = customBucket;
        }
        String fileUrl = "";
        try {
            if (minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
                log.info("Bucket already exists.");
            } else {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
                minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucketName).config(READ_WRITE.replace(BUCKET_PARAM, bucketName)).build());
                log.info("create a new bucket.");
            }
            InputStream stream = file.getInputStream();
            // 获取文件名
            String fileName = file.getOriginalFilename();
            if (StringUtils.isBlank(fileName)) {
                fileName = file.getName();
            }
            String objectName = bizPath + StringPool.SLASH + (!fileName.contains(StringPool.DOT) ? fileName + StringPool.UNDERSCORE + System.currentTimeMillis() : fileName.substring(0, fileName.lastIndexOf(StringPool.DOT)) + StringPool.UNDERSCORE + System.currentTimeMillis() + fileName.substring(fileName.lastIndexOf(StringPool.DOT)));
            PutObjectArgs objectArgs = PutObjectArgs.builder().object(objectName)
                    .bucket(bucketName)
                    .stream(stream, stream.available(), -1).build();
            minioClient.putObject(objectArgs);
            stream.close();
            fileUrl = agentMinioUrl + StringPool.SLASH + bucketName + StringPool.SLASH + objectName;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("MinioUtil upload error!!!" + e.getMessage());
        }
        return fileUrl;
    }
}
